package com.android.thelastnoet.customView;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.thelastnoet.LockActivity;
import com.android.thelastnoet.R;

public class DropDownView extends LinearLayout implements View.OnTouchListener {

    /**
     * 下拉状态
     */
    public static final int STATUS_PULL_TO_LOCK = 0;

    /**
     * 释放立即刷新状态
     */
    public static final int STATUS_RELEASE_TO_LOCK = 1;

    /**
     * 未下拉状态
     */
    public static final int STATUS_LOCK_FINISHED = 2;

    /**
     * 下拉头部回滚的速度
     */
    public static final int SCROLL_SPEED = -20;

    /**
     * 当前处理什么状态，可选值有
     * STATUS_PULL_TO_LOCK
     * STATUS_RELEASE_TO_LOCK
     * STATUS_LOCK_FINISHED
     */
    private int currentStatus = STATUS_LOCK_FINISHED;

    /**
     * 下拉头的View
     */
    private View header;
    /**
     * 显示内容的LinearLayout
     */
    private LinearLayout content_layout;
    /**
     * 需要去下拉刷新的RecyclerView
     */
    private RecyclerView recyclerView;
    /**
     * 手指按下时的屏幕纵坐标
     */
    private float yDown;
    /**
     * 在被判定为滚动之前用户手指可以移动的最大值。
     */
    private int touchSlop;
    /**
     * 下拉头的高度
     */
    private int hideHeaderHeight;
    /**
     * 下拉头的布局参数
     */
    private MarginLayoutParams headerLayoutParams;
    /**
     * 当前是否可以下拉，只有ListView滚动到头的时候才允许下拉
     */
    private boolean ableToPull;
    /**
     * 下拉刷新的回调接口
     */
    private PullToRefreshListener mListener;
//-------------------------------------------------------------------------------

    /**
     * 下拉刷新控件的构造函数，会在运行时动态添加一个下拉头的布局
     *
     * @param context
     */
    public DropDownView(Context context, AttributeSet attrs) {
        super(context);
        header = LayoutInflater.from(context).inflate(R.layout.drop_down_header, null, true);
        content_layout=header.findViewById(R.id.content_layout);
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        setOrientation(VERTICAL);
        addView(header, 0);
    }

    /**
     * 进行一些关键性的初始化操作，比如：将下拉头向上偏移进行隐藏，给ListView注册touch事件。
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            hideHeaderHeight = -header.getHeight();
            headerLayoutParams = (MarginLayoutParams) header.getLayoutParams();
            headerLayoutParams.topMargin = hideHeaderHeight;
            recyclerView = (RecyclerView) getChildAt(1);
            recyclerView.setOnTouchListener(this);
            if (currentStatus == STATUS_LOCK_FINISHED) {
                new HideHeaderTask();
            }
        }
    }

    /**
     * 当ListView被触摸时调用，其中处理了各种下拉刷新的具体逻辑。
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        setIsAbleToPull(event);
        if (ableToPull) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    yDown = event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float yMove = event.getRawY();
                    int distance = (int) (yMove - yDown);
                    if (distance <= 0 && headerLayoutParams.topMargin <= hideHeaderHeight) {
                        return false;
                    }
                    if (distance < touchSlop) {
                        return false;
                    }
                    if (headerLayoutParams.topMargin > 0) {
                        currentStatus = STATUS_RELEASE_TO_LOCK;
                    } else {
                        currentStatus = STATUS_PULL_TO_LOCK;
                    }
                    // 通过偏移下拉头的topMargin值，来实现下拉效果
                    headerLayoutParams.topMargin = (distance / 2) + hideHeaderHeight;
                    header.setLayoutParams(headerLayoutParams);
                    break;
                case MotionEvent.ACTION_UP:
                default:
                    if (currentStatus == STATUS_RELEASE_TO_LOCK) {
                        // 松手时如果是释放立即解锁状态，就去调用正在跳转活动
                        new jumpTask().execute();
                    } else if (currentStatus == STATUS_PULL_TO_LOCK) {
                        new HideHeaderTask().execute();
                    }
                    break;
            }
            if (currentStatus==STATUS_RELEASE_TO_LOCK){
                content_layout.setVisibility(View.VISIBLE);
                recyclerView.setPressed(false);
                recyclerView.setFocusable(false);
                recyclerView.setFocusableInTouchMode(false);
                return true;
            }
        }
        return false;
    }

    public void setOnRefreshListener(PullToRefreshListener listener) {
        mListener = listener;
    }

    /**
     * 根据当前ListView的滚动状态来设定 {@link #ableToPull}的值，
     * 每次都需要在onTouch中第一个执行，这样可以判断出当前应该是滚动ListView，还是应该进行下拉。
     *
     * @param event
     */
    private void setIsAbleToPull(MotionEvent event) {
        View firstChild = recyclerView.getChildAt(0);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int firstVisiblePos = 0;
        if (layoutManager instanceof LinearLayoutManager) {
            LinearLayoutManager linearManager = (LinearLayoutManager) layoutManager;
            firstVisiblePos = linearManager.findFirstVisibleItemPosition();
        }
        if (firstVisiblePos == 0 && firstChild.getTop() == 0) {
            if (!ableToPull) {
                yDown = event.getRawY();
            }
            ableToPull = true;
        } else {
            if (headerLayoutParams.topMargin != hideHeaderHeight) {
                headerLayoutParams.topMargin = hideHeaderHeight;
                header.setLayoutParams(headerLayoutParams);
            }
            ableToPull = false;
        }
    }
    /**
     * 当所有的刷新逻辑完成后，记录调用一下，否则你的ListView将一直处于正在刷新状态。
     */
    public void finishRefreshing() {
        currentStatus = STATUS_LOCK_FINISHED;
        new HideHeaderTask().execute();
    }

    /**
     * 隐藏下拉头的任务，当未进行下拉刷新或下拉刷新完成后，此任务将会使下拉头重新隐藏
     */
    class HideHeaderTask extends AsyncTask<Void, Integer, Integer> {
        @Override
        protected Integer doInBackground(Void... voids) {
            int topMargin = headerLayoutParams.topMargin;
            while (true) {
                topMargin = topMargin + SCROLL_SPEED;
                if(topMargin<=hideHeaderHeight){
                    topMargin=hideHeaderHeight;
                    break;
                }
                publishProgress(topMargin);
            }
            return topMargin;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            headerLayoutParams.topMargin=values[0];
            header.setLayoutParams(headerLayoutParams);
        }

        @Override
        protected void onPostExecute(Integer integer) {
            headerLayoutParams.topMargin = integer;
            header.setLayoutParams(headerLayoutParams);
            currentStatus = STATUS_LOCK_FINISHED;
        }
    }


    class jumpTask extends AsyncTask<Void, Integer, Void>{

        @Override
        protected Void doInBackground(Void... voids) {
            int topMargin = headerLayoutParams.topMargin;
            while (true) {
                topMargin = topMargin + SCROLL_SPEED;
                if (topMargin <= 0) {
                    topMargin = 0;
                    break;
                }
                publishProgress(topMargin);
                sleep(10);
            }
//            currentStatus = STATUS_REFRESHING;
            publishProgress(0);
            if (mListener != null) {
                mListener.onRefresh();
            }
            return null;
        }
    }

    /**
     * 使当前线程睡眠指定的毫秒数。
     *
     * @param time 指定当前线程睡眠多久，以毫秒为单位
     */
    private void sleep(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public interface PullToRefreshListener {
        /**
         * 刷新时会去回调此方法，在方法内编写具体的刷新逻辑。注意此方法是在子线程中调用的， 你可以不必另开线程来进行耗时操作。
         */
        void onRefresh();
    }


}
